package edu.udel.gemini.repository;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import edu.udel.gemini.model.Instruction;
import edu.udel.gemini.model.LogicUnit;
import edu.udel.gemini.model.Memory;
import edu.udel.gemini.model.Parser;
import edu.udel.gemini.model.Register;

@Component
public class CentralProcessingUnit implements ProcessingUnit {
		
	private Memory memory;
	private Parser parser;
	private LogicUnit alu;
	private List<Register> registers;
	
	public CentralProcessingUnit() {
		alu = new LogicUnit();
		memory = new Memory();	
		registers = new ArrayList<Register>();
		registers.add(new Register("ZERO", 0));
		registers.add(new Register("ONE", 1));
		registers.add(new Register("PC", 1));
		registers.add(new Register("MAR"));
		registers.add(new Register("MDR"));
		registers.add(new Register("TEMP"));
		registers.add(new Register("IR"));
		registers.add(new Register("CC"));
	}
	
	@Override
	public List<Register> getRegisters() {
		List<Register> registers = new ArrayList<Register>();
		registers.addAll(alu.getRegisters());
		registers.addAll(this.registers);
		return registers;
	}
	
	@Override
	public Instruction getInstructionByLine(int line) {
		return this.memory.getInstructions().get(line);
	}

	@Override
	public List<Instruction> getInstructions() {
		List<Instruction> instructions = this.memory.getInstructions();
		Collections.sort(instructions, new Comparator<Instruction>() {
		      public int compare(Instruction o1, Instruction o2) {
		        return o1.getLine() - o2.getLine();
		      }
		    });
		return instructions;
	}

	@Override
	public boolean parseFile(MultipartFile multipartFile) {
		try {
			this.memory.setInstructions(parser.getInstructionsFromFile(multipartFile));
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

}
